using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;

namespace Server.Items
{
	public abstract class BaseRanged : BaseWeapon
	{
		public abstract int EffectID { get; }
		public abstract Type AmmoType { get; }
		public abstract Item Ammo { get; }

		public override int DefHitSound { get { return 0x234; } }
		public override int DefMissSound { get { return 0x238; } }

		public override SkillName DefSkill { get { return SkillName.Bow; } }
		public override WeaponType DefType { get { return WeaponType.Ranged; } }
		public override WeaponAnimation DefAnimation { get { return WeaponAnimation.ShootXBow; } }

		public virtual SkillName AccuracySkill { get { return SkillName.Bow; } }

		public BaseRanged(int itemID)
			: base(itemID)
		{
		}

		public BaseRanged(Serial serial)
			: base(serial)
		{
		}

		public override TimeSpan OnSwing(Mobile attacker, Mobile defender)
		{
			WeaponAbility a = WeaponAbility.GetCurrentAbility(attacker);

			TimeSpan weaponSpeed = TimeSpan.FromSeconds(Speed / 10);

			if (DateTime.Now > (attacker.LastMoveTime + weaponSpeed) || (WeaponAbility.GetCurrentAbility(attacker) is MovingShot))
				return base.OnSwing(attacker, defender);

			return weaponSpeed;
		}

		public override bool CheckHit(Mobile attacker, Mobile defender)
		{
			if (OnFired(attacker, defender))
				return base.CheckHit(attacker, defender);

			return false;
		}

		public override void OnHit(Mobile attacker, Mobile defender)
		{
			if (attacker.Player && !defender.Player && (defender.Body.IsAnimal || defender.Body.IsMonster) && 0.4 >= Utility.RandomDouble())
				defender.AddToBackpack(Ammo);

			base.OnHit(attacker, defender);
		}

		public override void OnMiss(Mobile attacker, Mobile defender)
		{
			if (attacker.Player && 0.4 >= Utility.RandomDouble())
				Ammo.MoveToWorld(new Point3D(defender.X + Utility.RandomMinMax(-1, 1), defender.Y + Utility.RandomMinMax(-1, 1), defender.Z), defender.Map);

			base.OnMiss(attacker, defender);
		}

		public virtual bool OnFired(Mobile attacker, Mobile defender)
		{
			Container pack = attacker.Backpack;

			if (attacker.Player && (pack == null || !pack.ConsumeTotal(AmmoType, 1)))
				return false;

			attacker.MovingEffect(defender, EffectID, 18, 1, false, false);

			return true;
		}

		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write((int)0); // version
		}

		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt(); // version
		}
	}
}